package com.guan.core;

import com.guan.core.annotation.ResponseBody;
import com.guan.core.entity.ReturnContent;
import com.guan.core.util.Contants;
import com.guan.core.util.ReturnType;
import com.guan.util.SystemUtil;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 * MVC框架的核心控制器
 * Created by Administrator on 2018/1/16 0016.
 */
@SuppressWarnings("all")
public class DispathServlet extends HttpServlet{
    private BeanContext beanContext;
    @Override
    public void init(){
        //从应用上下文中拿到Bean容器
       beanContext =(BeanContext)this.getServletContext().getAttribute(Contants.CONTEXT_NAME);
    }
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //拿到请求的路径
        String contextPath = req.getContextPath();
        //初始化页面路径，在页面css与js引入时使用
        SystemUtil.initBasePath(req);
        String uri = req.getRequestURI();
        String mappingPath = uri.substring(uri.indexOf(contextPath)+contextPath.length(),uri.indexOf(".do"));
        /**
         * 1、通过映射路径去获取Methon 然后要反射调用
         * 2、反射调用离不开对象实例，所以要获取控制器实例
         * 3、然后通过反射调用
         */
        Method method = beanContext.getExecMethod(mappingPath);
        //通过类实例拿到类型，进一步拿到controller
        BaseController controller = beanContext.getController(method.getDeclaringClass().getName());
        try {
            //初始化
            controller.init(req,resp);
            if(method.isAnnotationPresent(ResponseBody.class)){
                method.invoke(controller);
            }else {
                CustomView customView = (CustomView) method.invoke(controller);
                ReturnType returnType = customView.getReturnType();
                ReturnContent content = customView.getReturnContent();
                switch (returnType) {
                    case FORWORD:
                        req.getRequestDispatcher(Contants.VIEW_PREFIX + content.getUrl() + Contants.VIEW_SUFIX).forward(req, resp);
                        break;
                    case REDIRECT:
                        resp.sendRedirect(contextPath + "/" + content.getUrl());
                        break;
                    case JSON:
                        PrintWriter writer = resp.getWriter();
                        writer.print(content.getJSON());
                        writer.close();
                        break;
                    case FORWORDCHAIN:
                        req.getRequestDispatcher(contextPath + "/" + content.getUrl()).forward(req, resp);
                        break;
                    default:
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
